<?php
namespace Client\Controller;

use Zend\View\Model\ViewModel;
use Zend\Db\Sql\Expression;
use Client\Exception\ClientException;
use Client\Common\LoggerHelper;
use Client\Lib\CLogFileHandler;
use Client\Lib\Log;
use Client\Lib\WxPayApi;
use Client\Lib\WxPayUnifiedOrder;
use Client\Lib\WxPayConfig;
use Client\Lib\JsApiPay;
use Client\Model\User;
use Client\Model\Organization;
use Client\Common\CategoryHelper;
use Client\Model\Order;


class OrderController extends InitializeController
{   
    //异步回调通知地址
    private $notify_url = "http://hy.zsdyzb.com/notify/wechat";
    
    /*
     * 继承，根据商城类型显示不同的view
     */
    public function indexAction(){
        $request = $this->getRequest();
        $org_id = $request->getPost('org_id');       
        $proArray = $this->getProArray();
        //
        $order = array();
        $orderItems = $this->getOrderItems($proArray);
        $totalPrice = $this->getTotalPrice($orderItems);
        $payPrice = $this->getPayPrice($totalPrice);
        
        //取得单位信息
        $org = $this->getOrganizationTable()->getInfoById($org_id);
        
        //取得代金券信息
        $query = array(
            'org_id'  => $org_id,
            'user_id' => $this->user_id,
        );
        $voucherList = $this->getVoucherTable()->getUseableList($query,$totalPrice);

        
        $order['list'] = $orderItems;
        $order['totalPrice'] = number_format($totalPrice,2,'.','');
        $order['payPrice'] = number_format($payPrice,2,'.','');
        
        $view_data = array(
           'proJson' => base64_encode(json_encode($proArray)),
           'orgInfo' => $org,
           'buyProInfo' => $order,
           'voucherList' => $voucherList,
            'voucherJson' => json_encode($voucherList)
        );
        
        if ($org['org_type'] == Organization::TYPE_FOOD) {
            $response_res = $this->getOrganizationAddrTable()->findAllByOrgId($org_id);
            $view_data['cates'] = CategoryHelper::unlimitedForLayer($response_res, $name = 'child', $pid = 0);
            $view = new ViewModel($view_data);
            $view->setTemplate('client/order/index.phtml'); 
        } else {
            $view = new ViewModel($view_data);
            $view->setTemplate('client/order/index-mall.phtml');
        }
        return $view;
    }
    
    private function getProArray()
    {
        $proList = $this->request->getPost('proList');
        $numList = $this->request->getPost('numList');
        //格式化购买的商品
        $proArry = array();
        $temProArry = explode("|",$proList);
        $temNumArry = explode("|",$numList);
        foreach ($temProArry as $key => $temPro){
            if($temPro != ''){
                $proArry[$temPro] = $temNumArry[$key];
            }
        }
        return $proArry;
    }
    
    /**
     * 
     */private function getOrderItems($proArry)
    {
        $orderItems = array();
        $proList = $this->getProductTable()->getBuyProList(array_keys($proArry));
        foreach ($proList as $key=>$pro)
        {
            $pro['num'] = $proArry[$pro['product_id']];
            array_push($orderItems, $pro);
        }
        return $orderItems;
    }
    
    /**
     *
     */private function getTotalPrice($orderItems)
     {
         $totalPrice = 0;
         foreach ($orderItems as $key=>$pro)
         {
             $totalPrice += $pro['product_price'] * $pro['num'];
         }
         return $totalPrice;
    }
    
    /**
     *
     */private function getPayPrice($totalPrice)
     {
         $payPrice = $totalPrice;
         return $payPrice;
    }
    
    /**
     * for test
     */
    public function testUseVoucherAction(){
        $request = $this->getRequest();
        $this->user_id = $request->getPost('user_id');
        $voucher_id = $request->getPost('voucher_id');
        $org_id = $request->getPost('org_id');
        $totalPrice = $request->getPost('totalPrice');
        $voucher = $this->getVoucherTable()->getVoucherById($voucher_id);
        echo $result = User::canUseVoucher($voucher,$this->user_id,$org_id,$totalPrice);
        die();
    }

    /*
     * 配餐创建订单
     */
    public function createAction(){
        $request = $this->getRequest();
        $org_id = $request->getPost('org_id');
        $proJson = $request->getPost('proJson');
        $proArray = json_decode(base64_decode($proJson),true);
        
        $address_info = $request->getPost('address_info');
        $receiver_name = $request->getPost('receiver_name');
        $cellphone = $request->getPost('cellphone');
        $receiver_mark = $request->getPost('receiver_mark');
        $send_time = $request->getPost('send_time');
        $order_mark = $request->getPost('order_mark');
        $voucher_id = $request->getPost('voucher_id');
        $org_address_id = $request->getPost('org_address_id');
              
        $db = $this->getAdapter()->getDriver()->getConnection();
        $db->beginTransaction();
        try
        {           
            //商家信息
            $org = $this->getOrganizationTable()->getInfoById($org_id);
            if(empty($org)) {
                throw new \Exception("地址不存在");
            }
                       
            //买家信息
            $user = $this->getUserTable()->getById($this->user_id);
            if(empty($user)) {
                throw new \Exception("买家不存在");
            }
            
            $orderItems = $this->getOrderItems($proArray);
            $totalPrice = $this->getTotalPrice($orderItems);
            $payPrice = $totalPrice;
            $discount = 0;
            $postage = 0;
            //如果使用代金券，验证是否可用
            if (!empty($voucher_id)) {
                $voucher = $this->getVoucherTable()->getVoucherById($voucher_id);
                if(empty($voucher)) {
                    throw new \Exception("优惠券不存在");
                }
                if(!empty($voucher)) {               
                    $result = User::canUseVoucher($voucher,$this->user_id,$org_id,$totalPrice);
                    if (!$result) {
                        throw new ClientException('优惠券不能使用');
                    } else {
                        //增加折扣金额
                        $discount += $voucher->vt_price;
                        $set = array(
                          'has_use' => 1,  
                        );
                        $this->getVoucherTable()->update($set,array('id'=>$voucher_id));
                    }
                } 
            }
            
            //价格计算公式 ，最终实付价格为 商品总价  - 折扣 + 邮费
            $payPrice = $totalPrice - $discount + $postage;
            
            //插入订单
            $order = array(
                'user_id'=>$user['user_id'],
                'org_id'=>$org['org_id'],
                'voucher_id' => empty($voucher)? null: $voucher->id,
                'org_address_id' => empty($org_address_id)? null: $org_address_id,
                'org_name'=>substr($org['org_name'],0,50),
                'order_total_price'=>$payPrice,
                'order_create_time'=>new Expression('NOW()'),
                'address_info'=>$address_info,
                'receiver_name'=>$receiver_name,
                'cellphone'=>$cellphone,
                'receiver_mark'=>$receiver_mark,
                'send_time' =>$send_time,
                'order_mark'=>$order_mark,
                'discount' => $discount,
                'postage' => $postage,
                'order_type' =>Order::TYPE_FOOD
            );
            $this->getOrderTable()->insert($order);
            $lastOrderId = $this->getOrderTable()->lastInsertValue;
            
            $lastorder = $this->getOrderTable()->getById($lastOrderId);

            $lastorder->order_no = "1".date('ymd',strtotime($lastorder['order_create_time'])).
                sprintf("%08d", $lastorder['order_id']).rand(0,9);
    
            $lastorder->save();
            
            
            //插入订单商品
            foreach($orderItems as $item) {
                $orderItem = array(
                    'product_id'=>$item['product_id'],
                    'order_id'=>$lastOrderId,
                    'oi_name'=>$item['product_name'],
                    'oi_price'=>$item['product_price'],
                    'oi_image'=>$item['product_thumb_image'],
                    'oi_amount'=>$item['num'],
                    'oi_create_time'=>new Expression('NOW()'),
                    'oi_meal_send_time'=>$item['meal_send_time'],
                    'oi_meal_type'=>$item['meal_type'],
                );
                $this->getOrderitemTable()->insert($orderItem);
            }
            
            $db->commit();
            
            return $this->redirect()->toRoute('order', array(
                'action' => 'payment',
                'id' => $lastorder->order_no
            ));       
        } 
        catch(\Exception $e)
        {
            $db->rollBack();
            LoggerHelper::client_exception($e);
            throw new ClientException('3002');
        }      
    }
    
    /*
     * 商户创建订单
     */
    public function createMallAction(){
        $request = $this->getRequest();
        $org_id = $request->getPost('org_id');
        $proJson = $request->getPost('proJson');
        $proArray = json_decode(base64_decode($proJson),true);
    
        $address_info = $request->getPost('address_info');
        $receiver_name = $request->getPost('receiver_name');
        $cellphone = $request->getPost('cellphone');
        $receiver_mark = $request->getPost('receiver_mark');
        $send_time = $request->getPost('send_time');
        $order_mark = $request->getPost('order_mark');
        $voucher_id = $request->getPost('voucher_id');
        $org_address_id = $request->getPost('org_address_id');
    
        $db = $this->getAdapter()->getDriver()->getConnection();
        $db->beginTransaction();
        try
        {
            //商家信息
            $org = $this->getOrganizationTable()->getInfoById($org_id);
            if(empty($org)) {
                throw new \Exception("地址不存在");
            }
             
            //买家信息
            $user = $this->getUserTable()->getById($this->user_id);
            if(empty($user)) {
                throw new \Exception("买家不存在");
            }
    
            $orderItems = $this->getOrderItems($proArray);
            $totalPrice = $this->getTotalPrice($orderItems);
            $payPrice = $totalPrice;
            $discount = 0;
            $postage = 0;
            //如果使用代金券，验证是否可用
            if (!empty($voucher_id)) {
                $voucher = $this->getVoucherTable()->getVoucherById($voucher_id);
                if(empty($voucher)) {
                    throw new \Exception("优惠券不存在");
                }
                if(!empty($voucher)) {
                    $result = User::canUseVoucher($voucher,$this->user_id,$org_id,$totalPrice);
                    if (!$result) {
                        throw new ClientException('优惠券不能使用');
                    } else {
                        //增加折扣金额
                        $discount += $voucher->vt_price;
                        $set = array(
                            'has_use' => 1,
                        );
                        $this->getVoucherTable()->update($set,array('id'=>$voucher_id));
                    }
                }
            }
    
            //价格计算公式 ，最终实付价格为 商品总价  - 折扣 + 邮费
            $payPrice = $totalPrice - $discount + $postage;
    
            //插入订单
            $order = array(
                'user_id'=>$user['user_id'],
                'org_id'=>$org['org_id'],
                'voucher_id' => empty($voucher)? null: $voucher->id,
                'org_address_id' => empty($org_address_id)? null: $org_address_id,
                'org_name'=>substr($org['org_name'],0,50),
                'order_total_price'=>$payPrice,
                'order_create_time'=>new Expression('NOW()'),
                'address_info'=>$address_info,
                'receiver_name'=>$receiver_name,
                'cellphone'=>$cellphone,
                'receiver_mark'=>$receiver_mark,
                'send_time' =>$send_time,
                'order_mark'=>$order_mark,
                'discount' => $discount,
                'postage' => $postage,
                'order_type' => Order::TYPE_MALL
            );
            $this->getOrderTable()->insert($order);
            $lastOrderId = $this->getOrderTable()->lastInsertValue;
    
            $lastorder = $this->getOrderTable()->getById($lastOrderId);
    
            $lastorder->order_no = "1".date('ymd',strtotime($lastorder['order_create_time'])).
            sprintf("%08d", $lastorder['order_id']).rand(0,9);
    
            $lastorder->save();
    
            //插入订单商品
            foreach($orderItems as $item) {
                $orderItem = array(
                    'product_id'=>$item['product_id'],
                    'order_id'=>$lastOrderId,
                    'oi_name'=>$item['product_name'],
                    'oi_price'=>$item['product_price'],
                    'oi_image'=>$item['product_thumb_image'],
                    'oi_amount'=>$item['num'],
                    'oi_create_time'=>new Expression('NOW()'),
                );
                $this->getOrderitemTable()->insert($orderItem);
            }
            $db->commit();
    
            return $this->redirect()->toRoute('order', array(
                'action' => 'payment',
                'id' => $lastorder->order_no
            ));
        }
        catch(\Exception $e)
        {
            $db->rollBack();
            LoggerHelper::client_exception($e);
            throw new ClientException('3002');
        }
    }
  
    /*
     * 订单支付页面
     * 规则
     * 1. 绑定用户，在绑定商户页面可以使用余额和微信两种付费方式。
     * 2. 其余都只能使用微信付费方式。
     */
    public function paymentAction(){
        ini_set('date.timezone','Asia/Shanghai');

        $id = $this->params()->fromRoute('id', 0);
       
        $user = $this->getUserTable()->getById($this->user_id);
        if(empty($user)) {
            throw new ClientException('会员不存在');
        }
        $open_id = $user->open_id;
        
        $order = $this->getOrderTable()->getByOrderNo($id);
        
        $order['firstItem'] = $this->getOrderitemTable()->getFirstItem($order['order_id']);
        
        //wx支付配置
        $tools = new JsApiPay();
        $wxorder = $this->createWxOrder($order, $open_id,$this->notify_url);       
        if (!empty($wxorder['err_code']) && $wxorder['err_code'] == 'ORDERPAID') {
            $jsApiParameters = "{}";
        } else { 
            $jsApiParameters = $tools->GetJsApiParameters($wxorder);
        }
        
        if (!empty($user['org_id']) &&  $user['org_id'] == $order['org_id']) {
            $hasBalancePay = 1;
        } else {
            $hasBalancePay = 0;
        }

        return new ViewModel(array(
            'order' => $order,
            'user'=> $user,
            'jsApiParameters' => $jsApiParameters,
            'error_code' => empty($order['err_code'])? "":$order['err_code'],
            'hasBalancePay' => $hasBalancePay
        ));
    }
    
    
    
    /*
     * 余额支付
     */
    public function balancePayAction(){
        $request = $this->getRequest();

        $order_no = $request->getPost('order_no');
        
        $db = $this->getAdapter()->getDriver()->getConnection();
        $db->beginTransaction();
        try
        {           
            //订单信息
            $order = $this->getOrderTable()->getByOrderNo($order_no);
            if(empty($order)) {
                throw new \Exception("订单不存在");
            }
                       
            //买家信息
            $user = $this->getUserTable()->getById($order->user_id);
            if(empty($user)) {
                throw new \Exception("买家不存在");
            }
                       
            //检查余额是否足够
            if ($user->balance < $order->order_total_price) {
                throw new \Exception("余额不足");
            }
            
            //检查订单状态
            if ($order->status != 1) {
                throw new \Exception("订单状态异常");
            }
            
            $order->status = 2;
            $order->trade_channel = 'balance';
            $order->save();
    
            $user->balance = $user->balance - $order->order_total_price;
            $user->save();
            
            $db->commit();
            return $this->redirect()->toRoute('order', array(
                'action' => 'paymentDone',
                'id' => $order->order_no
            ));       
        } 
        catch(\Exception $e)
        {
            $db->rollBack();
            LoggerHelper::client_exception($e);
            throw new ClientException('3001');
        }
        
    }
    
    /*
     * 支付完成页面
     */
    public function paymentDoneAction(){
        $id = $this->params()->fromRoute('id', 0);
             
        $order = $this->getOrderTable()->getByOrderNo($id);
        
        $org = $this->getOrganizationTable()->getById($order['org_id']);
    
        $order['firstItem'] = $this->getOrderitemTable()->getFirstItem($order['order_id']);
    
        return new ViewModel(array(
            'order' => $order,
            'org'=> $org
        ));
    }
    
    /*
     * 微信支付
     */
    public function wechatpayAction(){
        $openId = 'omCUpuBGs3pfoexKvwCiUA2nNzc0';
        ini_set('date.timezone','Asia/Shanghai');

        //①、获取用户openid
        $tools = new JsApiPay();

        //初始化日志
        $logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log');
        $log = Log::Init($logHandler, 15);
        
        $input = new WxPayUnifiedOrder();
        $input->SetBody("test");
        $input->SetAttach("test");
        $input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));
        $input->SetTotal_fee("1");
        $input->SetTime_start(date("YmdHis"));
        $input->SetTime_expire(date("YmdHis", time() + 600));
        $input->SetGoods_tag("test");
        $input->SetNotify_url("http://paysdk.weixin.qq.com/example/notify.php");
        $input->SetTrade_type("JSAPI");
        $input->SetOpenid($openId);
        $order = WxPayApi::unifiedOrder($input);
        echo $jsApiParameters = $tools->GetJsApiParameters($order);
        
        die();
    }
    
    public function testPayAction(){
        $open_id = 'ol3D7wZKcgcyTKRVqsRuRmFz4Q3s';
        ini_set('date.timezone','Asia/Shanghai');
                              
        //初始化日志
        
        
        //$logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log');
        //$log = Log::Init($logHandler, 15);
        $tools = new JsApiPay();
        $order = array();
        $order = $this->createWxOrder($order, $open_id,$this->notify_url);
        
        if (!empty($order['err_code']) && $order['err_code'] == 'ORDERPAID') {
            $jsApiParameters = "{}";
        } else {
            $jsApiParameters = $tools->GetJsApiParameters($order);
        }
        
        return new ViewModel(array(
            'jsApiParameters' => $jsApiParameters,
            'error_code' => empty($order['err_code'])? "":$order['err_code'],
        ));
    }
    
    private function createWxOrder($order,$open_id,$notify_url)
    {
        //①、获取用户openid      
        $input = new WxPayUnifiedOrder();
        $input->SetBody($order->org_name."订单支付");
        $input->SetAttach("");
        $input->SetOut_trade_no($order->order_no);
        $input->SetTotal_fee((int)($order->order_total_price*100));
        $input->SetTime_start(date("YmdHis"));
        $input->SetTime_expire(date("YmdHis", time() + 600));
        $input->SetGoods_tag("");
        $input->SetNotify_url($notify_url);
        $input->SetTrade_type("JSAPI");
        $input->SetOpenid($open_id);
        return WxPayApi::unifiedOrder($input);        
    }
}





